# -*- coding:utf-8 -*-

import requests
import json
import csv
import os
from lxml import etree
import calendar
import time

requests.packages.urllib3.disable_warnings()


"""
B站
"""


class BililiUser():
    def __init__(self):
        self.headers = {
            'authority': 's.search.bilibili.com',
            'method': 'GET',
            'scheme': 'https',
            'accept': '*/*',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9',
            'dnt': '1',
            'referer': 'https://space.bilibili.com/188839285/video?tid=0&page=2&keyword=&order=pubdate',
            'sec-fetch-dest': 'script',
            'sec-fetch-mode': 'no-cors',
            'sec-fetch-site': 'same-site',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
        }

    # 获取列表信息
    def get_contents(self, cursor, type_name, cate_id, start_date, end_date):
        postData = {
            'main_ver': 'v3',
            'search_type': 'video',
            'view_type': 'hot_rank',
            'order': 'click',
            'copy_right': '-1',
            'cate_id': cate_id,
            'page': cursor,
            'pagesize': '20',
            'jsonp': 'jsonp',
            'time_from': start_date,
            'time_to': end_date,
            'callback': 'jsonCallback_bili_9094280181356547'
        }
        url = f"https://s.search.bilibili.com/cate/search"
        html = requests.get(url, headers=self.headers, params=postData, verify=False)
        str_json = html.text.replace(postData['callback'], "").replace("(", "").replace(")", "")
        data_json = json.loads(str_json)
        numPages = data_json['numPages']  # 总页数
        for d in data_json['result']:
            dict_data = dict()
            dict_data['小分区名'] = type_name
            dict_data['用户名'] = d['author']
            dict_data['标题'] = d['title']
            aid = d['id']
            bvid = d['bvid']
            dict_data['播放数量'] = d['play']
            dict_data['发布时间'] = d['pubdate']
            dict_data['视频链接地址'] = d['arcurl']
            if int(dict_data['播放数量']) >= 50000:
                # 获取视频信息投币枚数
                result = self.get_count(bvid, dict_data)
                if result == 1:
                    return 1
            else:
                return 0
        # 翻页
        if cursor <= numPages:
            print(f"===【{type_name}】====【{start_date}至{end_date}】=====第【{cursor + 1}】页=============")
            self.get_contents(cursor + 1, type_name, cate_id, start_date, end_date)


    # 获取播放数、弹幕数、点赞数、投硬币枚数、收藏人数、分享
    def get_count(self, bvid, dict_data):
        time.sleep(1)
        result = 0
        print("========获取获赞数量========")
        url = f"https://www.bilibili.com/video/{bvid}"
        html = requests.get(url, headers=self.headers, verify=False)
        root = etree.HTML(html.text)
        if html.status_code == 200:
            if len(root.xpath('//span[@class="view"]')) > 0:
                # 无具体数字
                dict_data['总播放数'] = "".join(root.xpath('//span[@class="view"]//text()')).replace("播放 ·", "").replace("\n", "").strip()
                dict_data['历史累计弹幕数'] = "".join(root.xpath('//span[@class="dm"]//text()')).replace("弹幕", "").replace("\n", "").strip()
                dict_data['点赞数'] = "".join(root.xpath('//span[@class="like"]//text()')).replace("点赞", "").replace("\n", "").strip()
                dict_data['投硬币枚数'] = "".join(root.xpath('//span[@class="coin"]//text()')).replace("投币", "").replace("\n", "").strip()
                dict_data['收藏人数'] = "".join(root.xpath('//span[@class="collect"]//text()')).replace("--", "").replace("收藏", "").replace("\n", "").strip()
                dict_data['分享'] = "".join(root.xpath('//span[@class="share"]//text()')).replace("分享", "").replace("\n", "").strip()
                # 格式化数据
                if dict_data['总播放数'].find("万") < 0:
                    dict_data['总播放数'] = str(int(dict_data['总播放数']) / 10000) + "万"
                if dict_data['历史累计弹幕数'].find("万") < 0:
                    if len(dict_data['历史累计弹幕数']) == 0:
                        dict_data['历史累计弹幕数'] = 0
                    dict_data['历史累计弹幕数'] = str(int(dict_data['历史累计弹幕数']) / 10000) + "万"
                if dict_data['点赞数'].find("万") < 0:
                    if len(dict_data['点赞数']) == 0:
                        dict_data['点赞数'] = 0
                    dict_data['点赞数'] = str(int(dict_data['点赞数']) / 10000) + "万"
                if dict_data['投硬币枚数'].find("万") < 0:
                    if len(dict_data['投硬币枚数']) == 0:
                        dict_data['投硬币枚数'] = 0
                    dict_data['投硬币枚数'] = str(int(dict_data['投硬币枚数']) / 10000) + "万"
                if dict_data['收藏人数'].find("万") < 0:
                    if len(dict_data['收藏人数']) == 0:
                        dict_data['收藏人数'] = 0
                    dict_data['收藏人数'] = str(int(dict_data['收藏人数']) / 10000) + "万"
                if dict_data['分享'].find("万") < 0:
                    if len(dict_data['分享']) == 0:
                        dict_data['分享'] = 0
                    dict_data['分享'] = str(int(dict_data['分享']) / 10000) + "万"
                # 保存数据
                self.ditc_to_csv("B站.csv", dict_data)
        elif html.status_code == 412:
            print("===========请求被拦截============")
            result = 1

        return result


    def ditc_to_csv(self, fileName: str, item: dict):
        """
        dict保存excel
        :param item: dict数据
        :return:
        """
        savefileName = "./" + fileName  # "./result.csv"
        headList = []  # 键list
        saveList = []  # 值list

        for k, v in item.items():
            headList.append(k)
            saveList.append(v)
        # 如果文件不存在，创建头
        if os.path.exists(savefileName) == False:
            with open(savefileName, "a", encoding="utf-8-sig", newline="") as csvfile:
                writer = csv.writer(csvfile)
                writer.writerow(headList)
        # 保存item中的数据
        with open(savefileName, "a", encoding="utf-8-sig", newline="") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(saveList)

        print(str(item))


if __name__ == '__main__':
    buser = BililiUser()
    list_type = ['201', '124', '207', '208', '209', '122']
    list_name = ['科学科普', '社科人文', '财经', '校园学习', '职业职场', '野生技术协会']

    for c in range(len(list_type)):
        # 循环12月
        for m in range(1, 13):
            monthRange = calendar._monthlen(2020, m)
            month = str(m).zfill(2)
            start_date = "2020" + month + "01"
            end_date = "2020" + month + str(monthRange)

            result = buser.get_contents(1, list_name[c], list_type[c], start_date, end_date)
            if result == 1:
                break